#ifndef BITMAP_H
#define BITMAP_H


typedef struct _CBitmap
{
	point		cSize;
	uint8 **	cBits;
	int32		cRowBytes;
	HBITMAP*	chBmp;
	bool8		cUpsideDown;
	void *		chRes;
	uint8 *		cAlphaBits;
	bool8		cTransparent;
	HDC			cDC;
	uint8		cVersion;
#ifdef	DEBUG_CBITMAP
	char *		cFilename;
#endif

//----------------------------------------------------------------------------
// use newCBitmap and deleteCBitmap instead of new and delete with _CBitmap.
private:
	_CBitmap() {}
	~_CBitmap() {}


} CBitmap;


// kharmon.  05-08-06.  Improved Graphics.
// these are the various image types supported now.  
// Used in CBitmapBuffer::cImageVersion variable.
enum ImageType
{
    BMP_8_BIT = 0,
    BMP_16_BIT,
    BMP_24_BIT,
    BMP_32_BIT,
    JPG_24_BIT,
    PNG,
    PNG_24_BIT,
    PNG_32_BIT
};


//----------------------------------------------------------------------------
// If you change this structure, please ensure it remains naturally packed
// on 4-byte boundaries.
//
typedef struct _CBitmapBuffer
{
	point		cSize;
	uint8		cTransparent;		// A bitfield would be better.
	uint8		cImageVersion;		// See "ImageType" enum.
	uint8		__reserved1;
	uint8		__reserved2;
	uint32		cImageOffset;
	uint32		cPaletteOffset;		// If zero (0), palette not present.
	uint32		cAlphaOffset;		// If zero (0), alpha channel not present.
	//
	// NOTE: Data follows immediately and in the order of offsets listed above.
	//       That is, image data, palette (optional), alpha channel (optional).
	//
} CBitmapBuffer;
#define endianCBitmapBuffer		"w4w4w1w1w1w1w4w4w4"


// PUBLIC Common interfaces
//
PLIBEXP pCBitmap	newCBitmap(const String& Name, uint32 Group);
PLIBEXP pCBitmap	newCBitmapSM(const String& Name, uint32 Group);

PLIBEXP pCBitmap	newCBitmapCopy(pCBitmap src);

// kharmon.  05-08-06.  Improved Graphics.
PLIBEXP pCBitmap    newCBitmapFromJPEG (const String& strFileName);
PLIBEXP pCBitmap    newCBitmapFromPNG (const String& strFileName);
PLIBEXP pCBitmap	newCBitmapFromBMP(const String& strFileName);

PLIBEXP pCBitmap	newCBitmapBlank(int32 Width, int32 Height);
PLIBEXP void		deleteCBitmap(pCBitmap This);

PLIBEXP pCBitmap	newResizeCBitmap(const String& Name, uint32 Group,
						int32 Width, int32 Height, int32 quality);
PLIBEXP pCBitmap	ResizeCBitmap(pCBitmap pSrc, int32 Width, int32 Height,
						int32 quality);
PLIBEXP pCBitmap	ResizeCBitmapColor (pCBitmap pSrc, int32 Width,
						int32 Height, int32 quality);
PLIBEXP	pCBitmap	RotateBitmap(pCBitmap src, int32 rotateAmt);
PLIBEXP	uint8*		CBitmapSaveFile(pCBitmap src, uint32* size);

#define 			CBitmapWidth(This)		((This) ? (This)->cSize.x : 0)
#define 			CBitmapHeight(This)		((This) ? (This)->cSize.y : 0)
#define				CBitmapLock(pCBitmap)
#define				CBitmapUnlock(pCBitmap)

#define 			CBitmapDC(This)		((This) ? (This)->cDC : 0)

PLIBEXP void		CBitmapBitmapBlt(pCBitmap This, int32 dx, int32 dy,
						pCBitmap Src);
PLIBEXP void		CBitmapTransparentBitmapBlt(pCBitmap This, int32 dx,
						int32 dy, pCBitmap Src);
PLIBEXP void		CBitmapBitmapBltSection(pCBitmap This, int32 dx, int32 dy,
						int32 sx, int32 sy, int32 sw, int32 sh, pCBitmap Src);
PLIBEXP void		CBitmapTransparentBitmapBltSection(pCBitmap, int32 dx,
						int32 dy, int32 sx, int32 sy, int32 sw, int32 sh,
						pCBitmap Src);

PLIBEXP void		CBitmapAdjustBitmapHLS( pCBitmap This, Real hue, 
											Real luminance, Real saturation );

// PUBLIC Platform interface
//
PLIBEXP pCBitmap	newCBitmapFrame(int32 Width, int32 Height, HDC BmpDC);
PLIBEXP	HBITMAP		CBitmapHBmp(pCBitmap This);
PLIBEXP HANDLE		CBitmapHRegion(pCBitmap This);

#define 			CBitmapBits(This)										\
						((This && (This)->cBits) ? *(This)->cBits : (uint8*)0)
#define				CBitmapRowBytes(This)									\
						(This ? (This)->cRowBytes : 0)
#define				CBitmapVersion(This)									\
						(This ? (This)->cVersion : 0)
#define 			CBitmapUpsideDown(This)									\
						((This) ? (This)->cUpsideDown : false)

#define 			CBitmapAlpha(This)										\
						((This) ? (This)->cAlphaBits : NULL)
PLIBEXP bool8 		CBitmapTransparent(pCBitmap This);
PLIBEXP void		CBitmapTransparent(pCBitmap This, bool8 trans);
bool8				CBitmapConstruct(pCBitmap This, const String& Name, int32 Width,
						int32 Height, uint8 * Bits, uint8 * pal, HDC BmpDC,
						void * hResource, bool8 transparent, uint8* alpha, uint8 version=0);
PLIBEXP	void		TransparentStretchBlt (pCBitmap Dest, int32 DestX, int32
						DestY, pCBitmap Src, int32 SrcW, int32 SrcH);

PLIBEXP pCBitmap	newAlphaBitmap(uint8 * bits, int32 width, int32 height);
//PLIBEXP void	TransparentAlphaBitmapBlt(pCBitmap This,	int32 DestX, int32 DestY, pCBitmap Src);

PLIBEXP	void		CBitmapAlphaBitmapBltSection(pCBitmap This,
						int32 dx, int32 dy, int32 sx, int32 sy,
						int32 sw, int32 sh, pCBitmap Src, uint8 alpha);

PLIBEXP void		BitmapBlit(pCBitmap Dest, int32 DestX, int32 DestY,
						pCBitmap Src);

bool8				CBitmapConstructFromBMP(pCBitmap, pBmp);
PLIBEXP bool8 		CBitmapCreateDIB(pCBitmap This);
void				CBitmapDestruct(pCBitmap);
PLIBEXP void		CBitmapNewPalette(LOGPALETTE *);
PLIBEXP void		CBitmapClear(pCBitmap This);
PLIBEXP void		CBitmapClearRect(pCBitmap This, int32 Left, int32 Top,
						int32 Right, int32 Bottom);
PLIBEXP void		CBitmapFillRect(pCBitmap This, int32 Left, int32 Top,
						int32 Right, int32 Bottom, COLORSIZE Color);
#define 			CBitmapRestoreSurfaces()	/* do nothing */
#define				CBitmapSetTransparentIndex(This, index)
PLIBEXP HBITMAP		CBitmapMonoMask(pCBitmap);
PLIBEXP pCBitmap 	CBitmapTransMask(pCBitmap);

PLIBEXP void 		BitmapBltSection(pCBitmap This,
						int32 dx, int32 dy, int32 sx, int32 sy,
						int32 sw, int32 sh, pCBitmap Src);

PLIBEXP void		CBitmapBitmapCopy(pCBitmap This, int32 dx, int32 dy, 
						pCBitmap Src);

PLIBEXP void		CBitmapBitmapCopySection(pCBitmap This, int32 dx, int32 dy,
						int32 sx, int32 sy, int32 sw, int32 sh, pCBitmap Src);

PLIBEXP void		CBitmapShade(pCBitmap This, COLORSIZE color);

PLIBEXP COLORSIZE   GetPixelColor(pCBitmap This, int32 nX, int32 nY);   // kharmon.  07-21-06.  #3077.  SicBo implementation.  

#ifdef DEBUG
PLIBEXP pCBitmap	newCBitmapFromAlpha(pCBitmap src);
#endif

#endif
